import { getAction, httpAction,uploadAction,deleteAction } from '@/api/manage'
import { initDictOptionMap } from '@/components/dict/YchDictSelectUtil'
import Sortable from 'sortablejs'
import {randomString} from "../utils/util";
import moment from "moment";
import YchConstant from "@/api/YchConstant";

export const FormMixin = {
  props: {
    editableList: {
      type: Array,
      default: () => []
    },
    requiredList: {
      type: Array,
      default: () => []
    },
    hiddenList: {
      type: Array,
      default: () => []
    },
    startPage: {
      type: Boolean,
      default: true
    },
  },
  data () {
    return {
      form: this.$form.createForm(this),
      model: {},
      spinning: 0,//遮罩
      sortables: {},
      disabledRulesBak: null,
      uploadUrl:{
        upload:YchConstant.PREFIX_SYSTEM + "/common/upload",
        delete:YchConstant.PREFIX_SYSTEM + "/common/deleteFile",
      },
      uploadTimestamp:''//上传时间戳
    }
  },
  created () {
    this.initDictConfig()
  },
  methods: {
    add (fks) {
      const model = {}
      if (fks) {
        fks.forEach(item => {
          model[item.colCode] = item.queryValue
        })
      }
      this.initFormData(model)
    },
    edit (id) {
      this.detail(id)
    },
    detail (id) {
      if (!this.url.queryById) {
        this.messageUtil.error('请设置url.queryById属性!')
        return
      }
      this.spinning++
      getAction(this.url.queryById, { id: id }).then((res) => {
        if (res.success) {
          this.initFormData(res.result)
        } else {
          this.messageUtil.warning(res.message)
        }
      }).finally(() => {
        this.spinning--
      })
      if (this.subTableConfig) {
        Object.keys(this.subTableConfig).forEach(key => {
          this.detailSubTableData(key, this.subTableConfig[key], id)
        })
      }
    },
    detailSubTableData (key, tab, id) {
      if (!tab.url) {
        this.messageUtil.error(`请设置子表${key}的url属性!`)
        return
      }
      this.spinning++
      getAction(tab.url, { id: id }).then((res) => {
        if (res.success) {
          tab.dataSource = res.result
        } else {
          this.messageUtil.warning(res.message)
        }
      }).finally(() => {
        this.spinning--
      })
    },
    initFormData (model) {
      this.form.resetFields()
      this.model = Object.assign({}, model)
      this.$nextTick(() => {
        this.form.setFieldsValue(this.lodash.pick(this.model, Object.keys(this.validatorRules)))
      })
    },
    async beforeSave(formData) {
      let that = this
      if (this.subTableConfig) {
        let subTableRef = Object.keys(this.subTableConfig);
        for(let i=0;i<subTableRef.length;i++){
          let $subTable = that.$refs[subTableRef[i]]
          const subTableValues = await this.getTableDataSource($subTable, this.subTableConfig[subTableRef[i]].dataSource);
          if(subTableValues==false){
            return
          }else{
            formData[subTableRef[i] + 'List'] = subTableValues
          }
        }
      }
      return formData;
    },
    save (func, processDefId) {
      // 触发表单验证
      this.form.validateFields(async (err, values) => {
        if (!err) {
          let httpUrl = ''
          let method = ''
          if (!this.model.id) {
            httpUrl += this.url.add
            method = 'post'
          } else {
            httpUrl += this.url.edit
            method = 'put'
          }
          if (processDefId) {
            httpUrl += '?processDefId=' + processDefId
          }
          let formData = Object.assign(this.model, values)
          //去空格
          this.trimData(formData)
          if (typeof this.beforeSave === 'function') {
            formData = await this.beforeSave(formData)
            if (!formData) {
              return
            }
          }
          this.spinning++
          httpAction(httpUrl, formData, method).then((res) => {
            if (res.success) {
              //上传及删除附件
              this.handleUpload(res,formData, func)
            } else {
              this.messageUtil.warning(res.message)
            }
          }).finally(() => {
            this.spinning--
          })
        }
      })
    },
    trimData(formData){
      let that = this
      if(formData){
        Object.keys(formData).forEach(key=>{
          if(formData[key] && typeof(formData[key])=='string'){
            formData[key] = formData[key].trim()
          }else if(formData[key] instanceof Object && formData[key].constructor == Array && formData[key].length){
            formData[key].forEach(item=>{
              that.trimData(item)
            })
          }else if (formData[key] instanceof Object && formData[key].constructor == Object){
            that.trimData(formData[key])
          }
        })
      }
    },
    editableModel() {
      if (this.disabledRules && !this.disabledRulesBak) {
        // 备份原始数据
        this.disabledRulesBak = {...this.disabledRules}
      }
      Object.keys(this.disabledRules).forEach(key => {
        if (this.startPage) {
          // 未启动时按表单默认配置
          this.disabledRules[key] = this.disabledRulesBak[key]
        } else {
          this.disabledRules[key] = !(this.editableList.indexOf(key) !== -1)
        }
      })
    },
    requiredModel() {
      // TODO 控制表单必填，缺少实现，缺少调用
    },
    hiddenBpmModel() {
      // TODO 控制表单必填，缺少实现，缺少调用
    },
    initDictConfig () {
      if (this.dictConfig) {
        let dictCodes = Object.keys(this.dictConfig).join(',')
        if (dictCodes && dictCodes.length > 0) {
          initDictOptionMap(dictCodes).then((res) => {
            if (res.success) {
              Object.keys(this.dictConfig).forEach(key => {
                this.$set(this.dictConfig, key, res.result[key])
              })
            }
          })
        }
      }
    },
    async getTableDataSource($table, dataSource) {
      const errMap = await $table.fullValidate(true).catch(errMap => errMap)
      if (errMap) {
        const msgList = []
        Object.values(errMap).forEach(errList => {
          errList.forEach(params => {
            const {rowIndex, column, rules} = params
            rules.forEach(rule => {
              msgList.push(this.$t('m.eform.formDesign.label.vxe_error', [rowIndex + 1, column.title, rule.message]))
            })
          })
        })
        this.$message.warning({
          icon: () => {
            return null
          },
          content: (
            <div style="color: red; max-hclassName: 400px; overflow: auto;">
          {
            msgList.map(msg => <div>{msg}</div>)
          }
          </div>
        )
      })
        return false
      } else {
        return dataSource
      }
    },
    async insertRow(tableId, dataSource, initData, activeCell, index) {
      const $table = this.$refs[tableId]
      let id = randomString(32)
      const record = {
        id: id,
        ...initData
      }
      if (typeof index === "undefined" || index === -1) {
        dataSource.push(record)
      } else {
        dataSource.splice(index, 0, record)
      }
      if (activeCell) {
        await $table.setActiveCell(record, activeCell)
      }
    },
    deleteRow(tableId, dataSource, key) {
      const $table = this.$refs[tableId]
      const selectRecords = $table.getCheckboxRecords()
      if (selectRecords.length === 0) {
        this.messageUtil.warning("没有选中数据")
        return
      }
      const idKey = key || 'id'

      const temp = {}
      dataSource.forEach((item, index) => {
        temp[item[idKey]] = index
      })
      let count = 0;
      selectRecords.forEach(item => {
        dataSource.splice(temp[item[idKey]] - count, 1)
        count++
      })
    },
    rowDrop(tableId, callback) {
      if (this.sortables[tableId]) {
        return
      }
      this.$nextTick(() => {
        const xTable = this.$refs[tableId]
        const sortableTool = Sortable.create(xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
          handle: '.drag-btn',
          onEnd: ({newIndex, oldIndex}) => {
            if (typeof callback === 'function') {
              callback.apply(this, [newIndex, oldIndex])
            }
          }
        })
        this.sortables[tableId] = sortableTool
      })
    },
    afterRowDrop(newIndex, oldIndex, dataSource) {
      const currRow = dataSource.splice(oldIndex, 1)[0]
      dataSource.splice(newIndex, 0, currRow)
    },
    resetOrderNum(dataSource, orderNumId) {
      dataSource.forEach((item, index) => {
        item[orderNumId || 'orderNum'] = index + 1
      })
    },
    setSubFieldValue(key, value, record) {
      record[key] = value
    },
    setSelectSubFieldValue(value,key, record){
      record[key] = value
    },
    formatterWithDate({cellValue, row, column}) {
      return cellValue ? moment(cellValue, "YYYY-MM-DD HH:mm:ss").format("YYYY-MM-DD") : cellValue
    },
    formatterWithDatetime({cellValue, row, column}) {
      return cellValue
    },
    formatOptionValue(subTable,field,value,multiple){
      if(this.subTableConfig[subTable]
        && this.subTableConfig[subTable].optionConfig
        && this.subTableConfig[subTable].optionConfig[field]
        && value){
        let options = this.subTableConfig[subTable].optionConfig[field];
        if(multiple){
          let values = ''
          for(let m=0;m<value.length;m++){
            for(let i=0;i<options.length;i++){
              if(value[m] == options[i].value){
                if(values && values.length>0){
                  values+= "," + options[i].label
                }else{
                  values = options[i].label
                }
              }
            }
          }
          return values
        }else{
          for(let i=0;i<options.length;i++){
            if(value == options[i].value){
              return options[i].label
            }
          }
        }
        return value
      }else{
        return value
      }
    },

    /**
     * 手动上传附件
     */
    handleUpload(saveRes,formData, func) {
      let that = this;
      let formId = saveRes.result?saveRes.result:that.model.id
      let fileList = []
      //上传文件列表
      let addFileList = []
      //删除文件列表
      let delFileList = []
      if(this.attachmentOptions && Object.keys(this.attachmentOptions).length > 0){
        Object.keys(this.attachmentOptions).forEach(key => {
          let dataId = this.attachmentOptions[key].dataId
          fileList.push(formData[dataId])
        })
      }

      fileList.forEach(item=>{
        if(item && item.length>0){
          item.forEach(file=>{
            if(!file.uploaded && file.originFileObj && !file.delete){
              addFileList.push(file)
            }else if(file.delete && file.uploaded){
              delFileList.push(file)
            }
          })
        }
      })

      if(addFileList.length>0 || delFileList.length>0){
        let promiseArr = []
        addFileList.forEach(file => {
          let promise = new Promise((resolve, reject) => {
            const formData = new FormData();
            formData.append('file', file.originFileObj);
            let url = that.uploadUrl.upload
            url += "?biz="+file.biz +"&formId="+formId+"&dataId="+file.dataId
            uploadAction(url, formData).then((res) => {
              if (res.success) {
                resolve(res)
              } else {
                reject(res)
              }
            })
          });
          promiseArr.push(promise)
        });
        delFileList.forEach(file=>{
          let promise = new Promise((resolve, reject) => {
            deleteAction(that.uploadUrl.delete, {url: file.url, id: file.uid}).then((res) => {
              if (res.success) {
                resolve(res)
              } else {
                reject(that.$t('m.common.tip.deleteFileFailed'))
              }
            })
          });
          promiseArr.push(promise)
        })
        this.confirmLoading ++
        //上传和删除附件处理
        Promise.all(promiseArr).then(res=>{
          that.uploadTimestamp = (new Date()).getTime()+""
          that.uploadCallback(saveRes,formData, func)
        }).catch(res=>{
          that.messageUtil.error(res.message);
        }).finally(() => {
          this.confirmLoading --
        })
      }else{
        this.uploadCallback(saveRes,formData, func)
      }
    },

    //附件上传回调
    uploadCallback(res,formData, func){
      if (!this.model.id) {
        this.model.id = res.result
      }
      if (typeof func === 'function') {
        func(this.model.id)
      }else{
        this.messageUtil.success(res.message)
      }
      this.$emit('refreshParent')
    },

  },
  mounted() {
    if (this.subTableConfig) {
      Object.keys(this.subTableConfig).forEach(key => {
        this.rowDrop(key, (newIndex, oldIndex) => {
          this.afterRowDrop(newIndex, oldIndex, this.subTableConfig[key].dataSource);
        })
      })
    }
  },
  beforeDestroy() {
    Object.keys(this.sortables).forEach(key => {
      this.sortables[key].destroy()
    })
    this.sortables = {}
  }
}
